(function($) {    
    var form = {        
        /*
         * 重置输入框.        
         * form.prototype.reset()方法本身支持重置到初始值的功能。
         */
        reset : function(formSelector) {            
            var $form = $(formSelector || 'form'),
                $formInputs = $form.find(".formInput"),
                $formItems = $form.find('.formField');                                        
            //清空所有显示声明的输入框.
            $formInputs.val('');
            //重置所有的自定义控件.
            $formItems.each(function(){
                var formfieldObj = $(this).data('formField');
                if(formfieldObj && formfieldObj.reset)  formfieldObj.reset();
            });
            //表单默认重置逻辑.
            $form.get(0).reset();
            //应用dom原生控件的默认值.
            $formInputs.each(function(){
                var $formInput = $(this),
                    defValue = $formInput.attr('defaultValue');
                if(!Type.isUndefined(defValue)){
                    $formInput.val(defValue);
                }
            });
            //重置form后，默认选中第一个输入框.
            var $formBoxes = $formInputs.filter(':text, :password'); 
            if($formBoxes.length){
                $formBoxes.get(0).focus();
            }
        },
        /**
         * 获取表单的值.
         * get form json value, use field name as json key.
         * @param isBoolTo_01 [{Boolean}] 返回的bool值是否转换成0-1.
         * 
         * Number(true) == 1
         * Number(false) == 0
         * 在MongoDB中，Boolean值用true/false表示。
         * 在MySql等关系型数据库中，Boolean值用1/0表示。
         */
        getValues : function(formSelector, isBoolTo_01) {
            var $form = $(formSelector || 'form'),
                formDataObj = {};  
            if(!$form.size()){
            	$form = $('body');
            }          
            //获取所有的输入框的值,除非包含类exceptFromForm.
            var textBoxs = $form.find(".formInput, :input").not(':checkbox, .exceptFromForm');
            for (var i = 0, len = textBoxs.length; i < len; i++) {
                var textBox = textBoxs[i],
                    textBoxKey = textBox.name || textBox.id;
                JSON.setPath(formDataObj, textBoxKey, textBox.value);
            }
            //所有复选框.
            var checkBoxs = $form.find("input[type=checkbox]").not('.exceptFromForm');
            for (var k = 0, kLen = checkBoxs.length; k < kLen; k++) {
                var checkBoxKey = checkBoxs[k].name || checkBoxs[k].id;
                if (Type.isUndefined(formDataObj[checkBoxKey])) {
                    var checkBoxItems = checkBoxs.filter('[name={0}],[id={0}]'.format(checkBoxKey));
                    //若仅有一项checkbox, 则返回选中状态.
                    if (checkBoxItems.length !== 1) {
                        formDataObj[checkBoxKey] = checkBoxItems.map(function() {
                            var $checkBox = $(this); 
                            if ($checkBox.prop('checked')) {
                                return $checkBox.val();
                            }
                        }).get();
                    } else {
                    	//若单组中仅有一个复选框，则返回true/false或0/1.
                        formDataObj[checkBoxKey] = $(checkBoxItems[0]).prop('checked');
                        if(isBoolTo_01 === true){
                        	formDataObj[checkBoxKey] = Number(formDataObj[checkBoxKey]);	
                        }
                    }
                }
            }
            //TODO 所有单选框（未实现）。
            //所有的自定义控件.
            var customFormFields = $form.find('.formField');
            for (var j = 0, jLen = customFormFields.length; j < jLen; j++) {
                var $customFieldItem = $(customFormFields[j]),
                    customFieldItemKey = $customFieldItem.attr('id') || $customFieldItem.attr('name'),
                    customFieldDataType = $customFieldItem.attr('dataType'),
                    customFieldValue = $customFieldItem.attr('selectedvalue');                
                //若不存在selectedValue值,则尝试使用关联控件的getValue().
                if(Type.isUndefined(customFieldValue)){    
                    var formFieldObj = $customFieldItem.data('formField');
                    if(formFieldObj && formFieldObj.getValue){
                        customFieldValue = formFieldObj.getValue();
                    }                    
                } 
                //表单域值类型转换.
                switch(customFieldDataType){
                    case 'int' :
                        customFieldValue = parseInt(customFieldValue);
                        break;
                    case 'bool' :
                        customFieldValue = Type.isString(customFieldValue) ? ( customFieldValue == 'true' ) : customFieldValue;
                        break;
                }
                formDataObj[customFieldItemKey] = customFieldValue;
            }            
            return formDataObj;
        },
        /**
         * 获取修改过的表单域值.
         */
        getChangedValues : function(formSelector, originalData) {
            //原始的表单域值默认被放置到全局对象 _data 中.
            originalData = originalData || window['_data'] || {};
            
            var formValues = this.getValues(formSelector), 
                changedFormValues = {};
            
            for(var formFieldKey in formValues) {
                if(originalData[formFieldKey] != formValues[formFieldKey] || formFieldKey == 'id'){
                    changedFormValues[formFieldKey] = formValues[formFieldKey];
                }
            }
            //从隐藏域中获取所有的值，放到changedFormValues中.
            //隐藏域中经常存放ID，type等属性，往往需要与修改后的属性一起提交到server。
            var $form = $(formSelector || 'form'); 
            $form.find('input:hidden').each(function(){
            	var $hidden = $(this),
            		key = $hidden.attr('id') || $hidden.attr('name');
            	changedFormValues[key] = $hidden.val();
            });            
            return changedFormValues;
        },
        //set form values.
        setValues : function(formSelector, formData) {        	
            var $form = $(formSelector || 'form');        
            //所有的输入框.    
            var textBoxs = $form.find(".formInput, :input").not(':checkbox, .exceptFromForm');
            for (var i = 0, ilen = textBoxs.length; i < ilen; i++) {
                var textBoxField = textBoxs[i],
                    textBoxFieldKey = textBoxField['name'] || textBoxField['id'],
                    textBoxFieldValue = formData[textBoxFieldKey];
                if (!Type.isUndefined(textBoxFieldValue)) {
                    textBoxField.value = String(textBoxFieldValue).unsafeString();
                }
            }                        
            //所有的自定义form控件.
            var customFormFields = $form.find('.formField');
            for (var j = 0, jLen = customFormFields.length; j < jLen; j++) {
                var $customFieldItem = $(customFormFields[j]),
                    customFormFieldKey = $customFieldItem.attr('id') || $customFieldItem.attr('name'),
                    customFormFieldObj = $customFieldItem.data('formField');
                if (customFormFieldObj && customFormFieldObj.setValue) {
                    customFormFieldObj.setValue(formData[customFormFieldKey]);
                } else {
                    $customFieldItem.html(formData[customFormFieldKey]);
                }
            }     
            //TODO 所有单选框（未实现）。       
            //所有的复选框.
            var $checkboxes = $form.find(':checkbox');
            var checkboxesMap = {};
            $checkboxes.each(function(){
            	var $checkbox = $(this),
            		checkboxKey = $checkbox.attr('name') || $checkbox.attr('id');
        		if(!checkboxesMap[checkboxKey]){
        			checkboxesMap[checkboxKey] = [];
        		}
        		checkboxesMap[checkboxKey].push($checkbox);
        	});
        	Object.each(checkboxesMap, function(checkboxKey, checkboxesArr){
        		if(checkboxesArr.length == 1){	//同组内仅一个复选框.
        			var checkboxValue = formData[checkboxKey];
        			if(Type.isArray(checkboxValue)){
        				checkboxValue = checkboxValue[0];
        			}
        			$(checkboxesArr[0]).prop('checked', Boolean(Number(checkboxValue)));
        		} else {	//同级内多个筛选框.
        			var checkboxValue = formData[checkboxKey];
        			if(!Type.isArray(checkboxValue)){
        				checkboxValue = [ checkboxValue ];
        			}
        			checkboxesArr.each(function($checkbox){
    					$checkbox.prop('checked', checkboxValue.contains($checkbox.val()));	
        			});
        		}
        	});
        },
        /**
         * 表单校验.
         * @return {Boolean}
         */
        validate : function(formSelector) {
            //重新校验前，需要清除上次校验的非法标识.
            this.clearInvalidMark();
            
            var $form = $(formSelector || 'form'),            
                $formItems = $form.find(".formItem"), 
                valid = true;
                
            for (var i = 0, iLen = $formItems.length; i < iLen; i++) {
                var $formItem = $($formItems[i]), 
                    $formInput = $formItem.find('.formInput'),
                    formItemValue = $.trim( $formInput.val() ),
                    errorMsg = undefined;
                    
                //不需要校验的域，添加class:noValidate.
                var $formField = $formItem.find('.formField:not(.noValidate)');
                if($formField.isExist() && $formField.data('formField') && Type.isFunction($formField.data('formField').getValue)){
                    formItemValue = $formField.data('formField').getValue();
                }                
                //若控件存在，但不显示，不校验.
                if( $formInput.isExist() && !$formInput.isVisible() ){
                    continue;
                }                
                //非空判断.
                if ($formItem.hasClass('required')) {
                    if (( formItemValue == '' && $formInput.addClass('invalid') ) || ($formField && $formField.attr('selectedvalue') == '' && $formField.addClass('invalid'))) {
                        valid = false;
                        errorMsg = '{0} is required!'.format( $formItem.find('label').text() );   
                        continue;                     
                    }
                }                
                //预定义校验类型.
                var validatorType = $formItem.attr('validator-type');
                if(validatorType){
                    if(!RegExp['isValid' + validatorType.capitalize()](formItemValue)){
                        valid = false;
                        errorMsg = 'Invalid {0}.'.format(validatorType);
                        continue;
                    }
                }                
                //正则表达式校验.
                var validatorRegExp = $formItem.attr('validator-regexp');
                if(validatorRegExp){
                    //var 暂时不实现.
                }                
                //最小输入字符串长度.
                var validatorMinlen = $formItem.attr('validator-minlen');
                if(validatorMinlen){
                    validatorMinlen = parseInt( $.trim(validatorMinlen) );
                    if(formItemValue.length < validatorMinlen){
                        valid = false;
                        errorMsg = $formItem.attr('error-text-minlen'); 
                        continue;
                    }
                }                
                //最大输入字符串长度.
                var validatorMaxlen = $formItem.attr('validator-maxlen');
                if(validatorMaxlen){
                    validatorMaxlen = parseInt( $.trim(validatorMaxlen) );
                    if(formItemValue.length > validatorMaxlen){
                        valid = false;
                        errorMsg = $formItem.attr('error-text-maxlen'); 
                        continue;
                    }
                }                
                //自定义判断.
                var validatorCustom = $formItem.attr('validator-custom');
                if(validatorCustom){                    
                    if(!(eval('({0})'.format(validatorCustom)))){
                        valid = false;
                        errorMsg = $formItem.attr('error-text-custom');
                        continue;    
                    }
                }                
                if(errorMsg){
                    $formItem.append('<div class="formTip formErrorTip">{0}</div>'.format(errorMsg));
                }               
            }            
            //自定义控件校验.
            var $customFormFields = $form.find('.customFormField');            
            $customFormFields.each(function(){
                var $customFormField = $(this),
                    customFormfieldObj = $customFormField.data('formField');
                if(customFormfieldObj){
                    if($customFormField.parent().hasClass('required') && customFormfieldObj.isEmpty){
                        if(customFormfieldObj.isEmpty()){
                            customFormfieldObj.markInvalid && customFormfieldObj.markInvalid(); 
                            valid = false;
                        }
                    }
                }
            });            
            return valid;
        },
        /**
         * 清除表单输入的非法标识.
         */
        clearInvalidMark : function(formSelector) {
            var $form = $(formSelector || 'form');
            $form.find('.formErrorTip').remove();
            $form.find('.invalid').removeClass('invalid');
        }
    };
    
    //------------------------------------------------------------------------
        
    ujs.define('form', 'ujs.browser', form);
    
})($); 